<h2 class="hide">{DO}用户</h2>
<div id="master-user-form"
     class="hide-roles"
     data-topple="hsForm"
     data-load-url="centra/master/user/info.act?id=${id}&amp;ab=.enfo&amp;with-roles=default"
     data-save-url="centra/master/user/save.act?id=${id}"
     data--0="initInfo:($(this).hsFind('%'))"
     data--1="_fill_head:(hsFormFillPict)">
    <form action="" method="POST" enctype="multipart/form-data" autocomplete="off">
        <input type="hidden" name="id" data-fn/>
        <div style="height: 0; overflow: hidden;">
            <input type="text"     name="_u"/>
            <input type="password" name="_s"/>
        </div>
        <div class="row">
            <div class="col-xs-6 base-info" style="overflow: auto;">
                <div class="form-group">
                    <label class="control-label">账号</label>
                    <input type="text" name="username" class="form-field form-control username" data-unique="centra/master/user/unique.act?id=${id}" autocomplete="off"/>
                </div>
                <div class="form-group">
                    <label class="control-label">口令</label>
                    <input type="password" name="password" class="form-field form-control" data-relate="passcode" data-error="请重复输入口令" placeholder="请重复输入口令" autocomplete="off"/>
                </div>
                <div class="form-group">
                    <input type="password" name="passcode" class="form-field form-control" data-repeat="password" data-error="请重复输入口令" placeholder="请重复输入口令" autocomplete="off"/>
                </div>
                <div class="form-group form-control-static" style="padding-top: 0;">
                    <label><input type="checkbox" name="password" value="*" class="non-password form-final" style="margin-right:1em;"/>清除口令</label>
                    <span style="margin-left:1em; margin-right:1em;">/</span><a href="javascript:;" class="new-password form-ifnal"><b>生成口令</b></a>
                </div>
                <div class="form-group">
                    <label class="control-label">昵称</label>
                    <input type="text" name="name" class="form-field form-control" required="required"/>
                </div>
                <div class="form-group dont-close">
                    <label class="control-label">头像</label>
                    <input name="head" type="hidden" class="form-final"/>
                    <input name="head" type="file" class="invisible" accept="image/*"/>
                    <ul data-fn="head" data-mode="pick" data-size="150*150" class="pickbox"></ul>
                    <button type="button" class="btn btn-default form-control" data-toggle="hsPict">请选择头像</button>
                    <p class="help-block text-error"></p>
                    <p class="help-block text-muted">缩略图比例 1:1, 推荐分辨率 150*150 到 300*300 (像素)</p>
                </div>
                <div class="form-group">
                    <label class="control-label">头衔</label>
                    <input type="text"  name="title" class="form-field form-control"/>
                    <label class="form-control-static">
                        <input type="hidden"   name="title_checked" value="0" class="form-final"/>
                        <input type="checkbox" name="title_checked" value="1" style="margin-right:1em;"/>
                        <span>已验证</span>
                    </label>
                    <div class="help-block text-error form-control-static"></div>
                </div>
                <div class="form-group">
                    <label class="control-label">邮箱</label>
                    <input type="email" name="email" class="form-field form-control" data-unique="centra/master/user/unique.act?id=${id}"/>
                    <label class="form-control-static">
                        <input type="hidden"   name="email_checked" value="0" class="form-final"/>
                        <input type="checkbox" name="email_checked" value="1" style="margin-right:1em;"/>
                        <span>已验证</span>
                    </label>
                    <div class="help-block text-error form-control-static"></div>
                </div>
                <div class="form-group">
                    <label class="control-label">手机</label>
                    <input type="tel"   name="phone" class="form-field form-control" data-unique="centra/master/user/unique.act?id=${id}"/>
                    <label class="form-control-static">
                        <input type="hidden"   name="phone_checked" value="0" class="form-final"/>
                        <input type="checkbox" name="phone_checked" value="1" style="margin-right:1em;"/>
                        <span>已验证</span>
                    </label>
                    <div class="help-block text-error form-control-static"></div>
                </div>
                <div class="form-group">
                    <label class="control-label">简介</label>
                    <textarea name="note" class="form-field form-control"></textarea>
                </div>
                <div class="form-group" style="margin-bottom: 0;">
                    <label class="control-label">状态</label>
                    <select name="state" class="form-field form-control"></select>
                </div>
            </div>
            <div class="col-xs-6 role-info" style="overflow: auto;">
                <div class="form-group">
                    <label class="control-label">所属分组</label>
                    <div class="form-control multiple">
                        <input type="hidden" name="units0..unit_id" class="form-final"/>
                        <ul class="repeated labelbox labelist units0" data-fn="units0..unit_id" data-icon-class="bi bi-arrows-expand">
                            <li class="label label-info template">
                                <i class="drag  pull-left  bi bi-arrows-expand"></i>
                                <a class="erase pull-right bi bi-x" href="javascript:;"></a>
                                <span  class="title"></span>
                                <input class="value" type="hidden" name="units0..unit_id" />
                            </li>
                        </ul>
                        <a href="javascript::" data-href="centra/master/unit/pick.html" data-toggle="hsFork" data-target="@">选择分组</a>
                    </div>
                </div>
                <div class="form-group">
                    <label class="control-label">管理分组</label>
                    <div class="form-control multiple">
                        <input type="hidden" name="units1..unit_id" class="form-final"/>
                        <ul class="repeated labelbox labelist units1" data-fn="units1..unit_id" data-icon-class="bi bi-arrows-expand">
                            <li class="label label-info template">
                                <i class="drag  pull-left  bi bi-arrows-expand"></i>
                                <a class="erase pull-right bi bi-x" href="javascript:;"></a>
                                <span  class="title"></span>
                                <input class="value" type="hidden" name="units1..unit_id" />
                            </li>
                        </ul>
                        <a href="javascript::" data-href="centra/master/unit/pick.html" data-toggle="hsFork" data-target="@">选择分组</a>
                    </div>
                </div>
                <div class="alert alert-info">注意: 如需要让用户管理分组和用户, 管理分组与用户/分组管理权限均需设置. 所属分组与管理分组可以互相拖拽, 无论设置哪个均拥有对应分组权限.</div>
                <div class="form-group" style="margin-bottom: 0;">
                    <label class="control-label">权限设置</label>
                    <input type="hidden" name="roles..role" class="form-final"/>
                    <div class="checkset" data-item-class="col-xs-6 col-lg-3"
                         data-fn="roles..role" data-ft="_checkset"
                         data-vl="roles" data-tl="text"
                         data-vk="name"  data-tk="text">
                    </div>
                </div>
            </div>
        </div>
        <hr/>
        <div class="row">
            <div class="col-xs-6 form-btns board">
                <button type="submit" class="commit btn btn-primary">提交</button>
                <button type="button" class="cancel btn btn-link"   >取消</button>
            </div>
        </div>
    </form>
</div>
<script type="text/javascript">
    (function($) {
        var context = $("#master-user-form");
        var loadbox = context.closest(".loadbox");
        var loadpms = hsSerialArr( loadbox );
        var units0Box = context.find("[data-fn='units0..unit_id']");
        var units1Box = context.find("[data-fn='units1..unit_id']");

        // 左右平衡大小, 需减掉上下部分的高度
        var h = $(window).height() - 70 - 96;
        context.find(".base-info").css("max-height", h);
        context.find(".role-info").css("max-height", h);

        // 权限、分组以及密码
        context.on("loadBack", function(ev, rd, xb) {
            if (!rd["enfo"]["roles..role"].length ) {
                context.find(".role-info").remove();
            } else {
                context.removeClass( "hide-roles" );
                // 重组名称, 加上路径
                $.each(rd["enfo"]["roles..role"], function(i,r) {
                    if (r.tabs && r.tabs.length) {
                        r.text  = r.tabs.join(" / ") +" / "+ r.text;
                    }
                });
            }

            // 填充分组选项
            if (rd.info) {
                if (rd.info.units) {
                    var units0 = [];
                    var units1 = [];
                    for(var i = 0; i < rd.info.units.length; i ++) {
                        var item = rd.info.units[i];
                        if (1 == item.type) {
                            units1.push(item);
                        } else {
                            units0.push(item);
                        }
                    }
                    hsFormFillFork.call(xb, units0Box, units0);
                    hsFormFillFork.call(xb, units1Box, units1);
                }
            } else {
                var ids = hsGetSerias(loadpms, "unit_id");
                if (ids) {
                    $.hsAjax({
                        url : "centra/master/unit/list.act",
                        data: {"id": ids, "ob": ["id"], "rb": ["id", "name"]},
                        dataType: "json",
                        success : function (rs) {
                            rs = hsResponse(rs);
                            if (rs.ok && rs.list) {
                                hsFormFillFork.call(xb, units0Box, rs.list);
                            }
                        }
                    });
                }
            }

            context.data("loading", true);
        });
        context.on("loadOver", function() {
            context.removeData("loading");
        });

        // 选择所属管理的分组
        // 规避重复选择
        units0Box.change(function (ev , v) {
            if (v) {var a = Object.keys(v) ;
                for(var i = 0; i < a.length; i ++) {
                    units1Box.find("[value='"+a[i]+"']").closest("li").remove();
                }
            }
        });
        units1Box.change(function (ev , v) {
            if (v) {var a = Object.keys(v) ;
                for(var i = 0; i < a.length; i ++) {
                    units0Box.find("[value='"+a[i]+"']").closest("li").remove();
                }
            }
        });
        // 双向拖拽交换
        units0Box.sortable({
            items: "li",
            connectWith: units1Box
        });
        units1Box.sortable({
            items: "li",
            connectWith: units0Box
        });
        units0Box.next().droppable({
            accept: "ul.units1 li",
            drop: function(ev, ui) {
                ui.draggable.fadeOut(function() {
                    ui.draggable.appendTo(units0Box).fadeIn();
                    ui.draggable.find("input").attr("name", "units0..unit_id");
                });
            }
        });
        units1Box.next().droppable({
            accept: "ul.units0 li",
            drop: function(ev, ui) {
                ui.draggable.fadeOut(function() {
                    ui.draggable.appendTo(units1Box).fadeIn();
                    ui.draggable.find("input").attr("name", "units1..unit_id");
                });
            }
        });

        // 选择与之关联的权限
        context.on("change", "[name='roles..role']", function() {
            if (context.data("loading")) {
                return; // 加载过程中避免频繁调用卡死页面
            }
            var area = $(this).closest(".form-group");
            if ($(this).prop("checked")) {
                    var r = $(this).data("rels");
                    if (r && r.length )
                area.find(":checkbox" )
                    .not (":checked"  )
                    .not (".checkall" )
                    .not (this)
                    .each(function( ) {
                    var v = $(this).val ( /**/ );
                    if ($.inArray(v, r) !== -1 ) {
                        $(this).prop("checked", true ).change();
                    }
                });
            } else {
                    var v = $(this).val ( /**/ );
                area.find(":checkbox" )
                  .filter(":checked"  )
                    .not (".checkall" )
                    .not (this)
                    .each(function( ) {
                    var r = $(this).data("rels");
                    if (r && r.length )
                    if ($.inArray(v, r) !== -1 ) {
                        $(this).prop("checked", false).change();
                    }
                });
            }
        });

        // 联系方式可验证开关
        context.on("change", "[name='phone'],[name='email']", function() {
            var area = $(this).closest(".form-group");
            if ($(this).val()) {
                area.find(":checkbox")
                    .prop( "disabled", false);
            } else {
                area.find(":checkbox")
                    .prop( "disabled", true )
                    .prop( "checked" , false);
            }
        });

        context.on("change", ".non-password", function() {
            if ($(this).prop( "checked" )) {
                context.find(":password").val ("");
                context.find(":password").prop("disabled", true );
            } else {
                context.find(":password").prop("disabled", false);
            }
        });
        context.on("click" , ".new-password", function() {
            context.find(".non-password").prop("checked" , false);
            newPassword (32);
        });
        function newPassword(l) {
            var pw = getPassword(l);
            $.hsMask({
                mode : "warn",
                html : "请务必记住新的密码, 提交后将以不可逆加密的形式进行存储."
            }, {
                label: "更换",
                glass: "btn-default",
                click: function(ev) {
                    ev.preventDefault();
                    pw = getPassword(l);
                    $(this).closest(".modal").find(".code").text(pw);
                }
            }, {
                label: "拷贝",
                glass: "btn-default",
                click: function(ev) {
                    ev.preventDefault();
                    $(this).closest(".modal").find(".code").hsCopy();
                }
            }, {
                label: "确认",
                glass: "btn-primary",
                click: function() {
                    context.find("[name=password],[name=passcode]").val(pw);
                }
            }).find(".alert-title").html('新密码: <b class="code">'+ pw +'</b>');
        }
        function getPassword(l) {
            var cs = [
                ['A', 'B', 'C', 'D', 'E', 'F', 'G',
                 'H', 'I', 'G', 'K', 'M', 'N',
                 'P', 'Q', 'R', 'S', 'T',
                 'U', 'V', 'W', 'X', 'Y'],
                ['a', 'b', 'c', 'd', 'e', 'f', 'g',
                 'h', 'i', 'g', 'k', 'm', 'n',
                 'p', 'q', 'r', 's', 't',
                 'u', 'v', 'w', 'x', 'y'],
                ['3', '4', '5', '6', '7', '8', '9'],
                ['@', '#', '$', '%', '&']
            ];
            var ps = [];
            var hasNum = false; // 至少含有一个数字
            var hasSym = false; // 至少含有一个符号
            for(var i = 0; i < l; i ++) {
                var j = Math.floor(Math.random() * 100);
                var x = j % cs.length;
                if (x === 2 && !hasNum) {
                    hasNum = true;
                } else
                if (x === 3 && !hasSym) {
                    hasSym = true;
                }
                if (i === 6 && !hasNum) {
                    x = 2;
                } else
                if (i === 7 && !hasSym) {
                    x = 3;
                }
                var y = j % cs[x].length;
                ps.push (cs[x][y]);
            }
            return ps.join("");
        }
    })(jQuery);
</script>